#include "task_lora.h"
#include "lib_string.h"
#include "com_lora.h"
#include "m_kl9.h"
#include "protocol_manage.h"
#include "param.h"
#include "flash_cpu.h"
#include "rtc.h"
#include "protocol_frj.h"

#define TASK_LORA_ECHO 	  1
#ifdef  TASK_LORA_ECHO
#define task_lora_printf 	raw_printf
#else
#define task_lora_printf
#endif

LoraEvt active_lora;
IDLE_QUEUE_MSG queue_lora[3];
extern volatile state_mechine   StateMechine[MAX_LORA_STA_NUM];

extern void frj_pkg_data_send(void);
extern void frj_pkg_plus_data_send(void);

static RAW_U16 lora_initial(LoraEvt *me, STATE_EVENT *e);
static RAW_U16 lora_process(LoraEvt *me, STATE_EVENT *e);

static void lora_ctor(LoraEvt *me)
{
  FSM_CONSTRUCTOR(&me->evt.super, (stm_state_handler)&lora_initial);
}

static RAW_U16 lora_initial(LoraEvt *me, STATE_EVENT *e)
{
  return STM_TRAN(&lora_process);
}

static RAW_U16 lora_process(LoraEvt *me, STATE_EVENT *e)
{
	RAW_U16 status = STM_RET_IGNORED;
	unsigned int len = 0;
	FlashParam *flash = 0;
	ProManage *pro = 0;
	FlashCpuParam *cpu = flash_cpu_param_get();
	
	switch(e->sig)
	{
		case STM_ENTRY_SIG:
		break;
		case LORA_HANDLE_SIG:
			switch((unsigned char)(active_lora.CurrentSta))
			{
				case AT_STATE_IDLE:
					StateMechine[active_lora.CurrentSta].timeoutTick = 0;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
				break;
				case AT_STATE_RESET_L:
					RESET_L;
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_1second;
				break;
				case AT_STATE_RESET_H:
					RESET_H;
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_1second;
				break;
				case AT_STATE_WAKEUP_L:
					WAKEUP_L;
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_1second;
				break;
				case AT_STATE_WAKEUP_H:
					WAKEUP_H;
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_1second;
				break;
				case AT_STATE_QUIT_TRSEND:
					lora_enter_at();
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
				break;
				case AT_STATE_AT:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "%s", "AT\r\n");
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
				case AT_STATE_POW:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "AT+POW=%02x\r\n", cpu->cpuParam.pow);
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
				case AT_STATE_TSF:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "AT+TSF=%02x\r\n", cpu->cpuParam.sf);
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
				case AT_STATE_RSF:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "AT+RSF=%02x\r\n", cpu->cpuParam.sf);
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
				case AT_STATE_TFREQ:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "AT+TFREQ=%x\r\n", cpu->cpuParam.txfreq);
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
				case AT_STATE_RFREQ:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "AT+RFREQ=%x\r\n", cpu->cpuParam.rxfreq);
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
				case AT_STATE_BW:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "AT+BW=%02x\r\n", cpu->cpuParam.bw);
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
				case AT_STATE_CRC:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "AT+CRC=%02x\r\n", cpu->cpuParam.crc);
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
				case AT_STATE_SYNC:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "AT+SYNC=%02x\r\n", cpu->cpuParam.sync);
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
				case AT_STATE_NET:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "AT+NET=%02x\r\n", cpu->cpuParam.net);
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
				case AT_STATE_CFG:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "%s", "AT+CFG?\r\n");
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
				case AT_STATE_ENTER_TRSEND:
					lora_enter_data();
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_1second;
				break;
				case AT_STATE_DATA:
					raw_printf("Data Mode OK!\r\n");
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_40second;
					flash =  flash_param_get();
					pro = protocol_manage_get();
					pro->pro_send(&(flash->param));
				break;
				case AT_STATE_ENTER_AT:
					lora_enter_at();
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_1second;
				break;
				case AT_STATE_EL:
					StateMechine[active_lora.CurrentSta].timeoutTick = Wait_Time_2second;
					raw_memset(StateMechine[active_lora.CurrentSta].buf, 0, LORA_BUF_SIZE);
					len = raw_sprintf(StateMechine[active_lora.CurrentSta].buf, "%s", "AT+EL=0000\r\n");
					task_lora_printf("%s\r\n", StateMechine[active_lora.CurrentSta].buf);
					if(StateMechine[active_lora.CurrentSta].operate != 0) 		StateMechine[active_lora.CurrentSta].operate(StateMechine[active_lora.CurrentSta].buf, len);
				break;
			}
		break;
		default: break;
	}
	return status;
}

void lora_task_init(void)
{
	lora_ctor(&active_lora);
	fsm_init(&active_lora.evt.super, 0);
}


